<script setup>
import { onMounted } from 'vue';

onMounted(()=>{
  /**
   * 5x5数字华容道，一共有25个格子，我们可以为每一个格子标记下标，通过下标来找到对应的div元素对象
   * 格子下标从0开始，每个格子的下标如下所示：
   *  0,  1,  2,  3,  4,
   *  5,  6,  7,  8,  9,
   * 10, 11, 12, 13, 14,
   * 15, 16, 17, 18, 19,
   * 20, 21, 22, 23, 24
   */
    /**
     * 定义数字数组numArray，值为0~25，该数组中的元素则为每个格子中显示的数字
     * 同时定义div元素节点对象的数组divObjArray，每一个数组元素均为div元素节点对象
     * 		通过遍历方式，依次对每个数组元素赋值
     * 
     * 为何div元素节点对象通过getElementsByClassName()方法一次性获取到一个对象数组呢？这样明显是更简洁啊
     * 		因为IE浏览器8.x及以下均不支持getElementsByClassName()方法，为了兼容IE 8.x以下，就放弃了该方式
     */
    var numArray = new Array(25);
    var divObjArray = new Array(25);
    for (var i = 0; i < divObjArray.length; i++) {
      numArray[i] = i + 1;
      divObjArray[i] = document.getElementById("index_" + i);
    }

    /**
     * 定义“开始游戏”按钮的元素节点对象startButton
     * 		开始游戏按钮绑定单击响应函数，当玩家点击按钮后，更改按钮显示字样，更改按钮颜色；
     * 		游戏顺利通关后，复位按钮；
     * 定义计时器timer
     * 		定时器设置计时函数timing，
     * 		当玩家点击开始按钮进入游戏后，定时器开始计时；
     * 		游戏顺利通关后，复位计时器；
     * 定义计时器所示时间文本的元素节点对象timeText
     * 		游戏快开始后，每秒显示当前所用时间；
     * 		游戏结束后，时间文本复位置空
     * 定义提示文字“目标图案”的元素节点对象promptText
     * 		当玩家进入游戏后，将该提示文字隐藏起来；
     * 		游戏结束后，提示文字再显示
     */
    var startButton = document.getElementById("startButton");
    var timer;
    var curTime = 0;
    var timeText = document.getElementById("outputTime");
    var promptText = document.getElementById("promptText");

    startButton.onclick = function () {
      if (startButton.innerHTML == "游戏中...") {
        return;
      }

      // 更改按钮显示字样，更改按钮颜色
      startButton.innerHTML = "游戏中...";
      startButton.style.backgroundColor = "#FF7575";

      // 随机分布1~25数字所在位置
      numArray.sort(function () {
        return Math.random() > 0.5 ? -1 : 1;
      });
      for (var i = 0; i < divObjArray.length; i++) {
        if (numArray[i] == 25) {
          divObjArray[i].innerHTML = "";
          divObjArray[i].style.backgroundColor = "#6C6C6C";
          continue;
        }
        divObjArray[i].innerHTML = numArray[i];
        divObjArray[i].style.backgroundColor = "#FFA042";
      }

      // 定时器开始计时
      setTimeout(timing, 1000);

      // 同步显示时间文本
      curTime = 0;
      timeText.value = curTime;

      // 将顶部的“目标图案”字样隐藏
      promptText.style.display = "none";

    }

    // 计时器
    function timing() {
      curTime++;
      timeText.value = curTime;
      timer = setTimeout(timing, 1000);
    }

    /**
     * 使用25代表空白格，通过变量emptyIndex存储该值所在格子的下标
     * 并声明更新25空白格位置的函数updateEmptyFun
     */
    var emptyIndex = 24;

    // 获取空白格所在下标
    function updateEmptyFun() {
      emptyIndex = numArray.indexOf(25);
    }

    /**
     * 为每一个格子绑定单击响应函数
     * 		这些格子按照点击移动时，是否有规律、规律是否一致，可以分为6组
     * 		第1组，没有统一规律的一组，下标分别为0,4,20,24的格子
     * 		第2组，移动规律为可以移动左、下、右，下标分别为1,2,3的格子
     * 		第3组，移动规律为可以移动左、上、右，下标分别为21，22，23的格子
     * 		第4组，移动规律为可以移动上、下、右，下标分别为5,10,15的格子
     * 		第5组，移动规律为可以移动上、下、左，下标分别为9,14,19的格子
     * 		第6组，移动规律为可以移动上、下、左、右，下标分别为6,7,8,11,12,13,16,17,18的格子
     * 
     * 将绑定单击响应函数公共部分抽取出来，作为公共函数updatePositionFun，减少冗余代码
     * 		公共函数部分包含更新25(即空白格子)在数组numArray中的位置，同时更新格子交换后的颜色、数值
     * 
     * 在每次位置更新结束之后，需要判断是否已经完成数字排序；方法为isGameOver
     * 		若当前空白格未在最后一位，则可直接认为游戏为通关
     * 		若当前空白格已经在最后一位，则判断前面的所有数字均按照升序排序
     */
    function updatePositionFun(divIndex) {
      if (startButton.innerHTML == "开始游戏") {
        return;
      }
      numArray[emptyIndex] = divObjArray[divIndex].innerHTML;
      numArray[divIndex] = 25;
      divObjArray[emptyIndex].innerHTML = divObjArray[divIndex].innerHTML;
      divObjArray[emptyIndex].style.backgroundColor = "#FFA042";
      divObjArray[divIndex].innerHTML = "";
      divObjArray[divIndex].style.backgroundColor = "#6C6C6C";
      if (divIndex == 24) {
        isGameOver();
      }
    }

    // 判断游戏是否通关
    function isGameOver() {
      for (var i = 0; i < numArray.length; i++) {
        if (numArray[i] != i + 1) {
          return;
        }
      }
      // 游戏通关，弹框告知玩家游戏顺利通关，以及所用时间
      alert("通关啦！ 用时：" + timeText.value + "s");
      // 将“开始游戏”按钮复位
      startButton.innerHTML = "开始游戏";
      startButton.style.backgroundColor = "#97CBFF";
      // 将计时器复位
      clearTimeout(timer);
      // 将顶部的“目标图案”字样设置为显示
      promptText.style.display = "block";
    }

    // 下标为0的格子的单击响应函数
    divObjArray[0].onclick = function () {
      updateEmptyFun();
      if (emptyIndex == 1 || emptyIndex == 5) {
        updatePositionFun(0);
      }
    }

    // 下标为4的格子的单击响应函数
    divObjArray[4].onclick = function () {
      updateEmptyFun();
      if (emptyIndex == 3 || emptyIndex == 9) {
        updatePositionFun(4);
      }
    }

    // 下标为20的格子的单击响应函数
    divObjArray[20].onclick = function () {
      updateEmptyFun();
      if (emptyIndex == 15 || emptyIndex == 21) {
        updatePositionFun(20);
      }
    }

    // 下标为24的格子的单击响应函数
    divObjArray[24].onclick = function () {
      updateEmptyFun();
      if (emptyIndex == 19 || emptyIndex == 23) {
        updatePositionFun(24);
      }
    }

    // 其他下标的格子的单击响应函数
    function resFun() {
      var curIndex;
      for (var i = 1; i < divObjArray.length; i++) {
        if (i >= 1 && i <= 3) {
          divObjArray[i].onclick = function () {
            updateEmptyFun();
            curIndex = divObjArray.indexOf(this);
            if (emptyIndex == curIndex - 1 || emptyIndex == curIndex + 1 || emptyIndex == curIndex + 5) {
              updatePositionFun(curIndex);
            }
          }
          continue;
        }
        if (i >= 21 && i <= 23) {
          divObjArray[i].onclick = function () {
            updateEmptyFun();
            curIndex = divObjArray.indexOf(this);
            if (emptyIndex == curIndex - 1 || emptyIndex == curIndex + 1 || emptyIndex == curIndex - 5) {
              updatePositionFun(curIndex);
            }
          }
          continue;
        }
        if (i == 5 || i == 10 || i == 15) {
          divObjArray[i].onclick = function () {
            updateEmptyFun();
            curIndex = divObjArray.indexOf(this);
            if (emptyIndex == curIndex - 5 || emptyIndex == curIndex + 5 || emptyIndex == curIndex + 1) {
              updatePositionFun(curIndex);
            }
          }
          continue;
        }
        if (i == 9 || i == 14 || i == 19) {
          divObjArray[i].onclick = function () {
            updateEmptyFun();
            curIndex = divObjArray.indexOf(this);
            if (emptyIndex == curIndex - 5 || emptyIndex == curIndex + 5 || emptyIndex == curIndex - 1) {
              updatePositionFun(curIndex);
            }
          }
          continue;
        }
        divObjArray[i].onclick = function () {
          updateEmptyFun();
          curIndex = divObjArray.indexOf(this);
          if (emptyIndex == curIndex - 5 || emptyIndex == curIndex + 5 || emptyIndex == curIndex - 1 || emptyIndex == curIndex + 1) {
            updatePositionFun(curIndex);
          }
        }

      }
    }
    resFun();

  
})
</script>
<template>
  <div id="huarong">
    <div class="div3">
      <span style="font-size: 50px;color: #D94600;" id="promptText">目标图案</span>
    </div>
    <div class="div1">
      <div class="div2" id="index_0">1</div>
      <div class="div2" id="index_1">2</div>
      <div class="div2" id="index_2">3</div>
      <div class="div2" id="index_3">4</div>
      <div class="div2" id="index_4">5</div>
      <div class="div2" id="index_5">6</div>
      <div class="div2" id="index_6">7</div>
      <div class="div2" id="index_7">8</div>
      <div class="div2" id="index_8">9</div>
      <div class="div2" id="index_9">10</div>
      <div class="div2" id="index_10">11</div>
      <div class="div2" id="index_11">12</div>
      <div class="div2" id="index_12">13</div>
      <div class="div2" id="index_13">14</div>
      <div class="div2" id="index_14">15</div>
      <div class="div2" id="index_15">16</div>
      <div class="div2" id="index_16">17</div>
      <div class="div2" id="index_17">18</div>
      <div class="div2" id="index_18">19</div>
      <div class="div2" id="index_19">20</div>
      <div class="div2" id="index_20">21</div>
      <div class="div2" id="index_21">22</div>
      <div class="div2" id="index_22">23</div>
      <div class="div2" id="index_23">24</div>
      <div class="div2" style="background-color: #6C6C6C;" id="index_24"></div>
    </div>
    <div class="div3">
      <button class="buttonStyle" id="startButton" name="button" value="StartButton">开始游戏</button>
      <span class="timeText">时间</span>
      <input class="inputStyle" type="text" name="outputTime" id="outputTime" value="" readonly="readonly" />
      <span class="timeText" style="margin-left: 0px;">s</span>
    </div>
  </div>
</template>


<style lang="scss">
#huarong {
  .div1 {
    width: 518px;
    height: 518px;
    background-color: #6C6C6C;
  }

  .div2 {
    width: 100px;
    height: 100px;
    float: left;
    margin-left: 3px;
    margin-top: 3px;
    background-color: #FFA042;
    text-align: center;
    font-size: 80px;
    color: #842B00;
  }

  .div3 {
    margin-top: 20px;
    width: 512px;
    height: 80px;
    /*border: solid;*/
    border-color: #000000;
    text-align: center;
  }

  .buttonStyle {
    width: 150px;
    height: 50px;
    font-size: 30px;
    margin-top: 15px;
    border-radius: 5%;
    background-color: #97CBFF;
  }

  .timeText {
    margin-left: 60px;
    font-size: 30px;
  }

  .inputStyle {
    float: auto;
    width: 100px;
    height: 30px;
    font-size: 30px;
  }
}
</style>